import { Base } from "../core/Base";
import { Engine } from "../Engine";
/**
 * 管线管理类
 * @author jiangjinwei
 */
class PipeManager extends Base {
  constructor(opts = {}) {
    super(opts);
    this.pipes = new Map();
  }
  get(archeType, options) {
    const id = archeType.id;
    if (this.pipes.has(id) && !options.isDiff) {
      return this.pipes.get(id);
    } else {
      let pipe = this.build(options);
      this.pipes.set(id, pipe);
      return pipe;
    }
  }
  build(options) {
    let { uniformsBindGroupLayout, config, _defs, vetexLayout } = options;
    // 创建pielineLayout
    const pipeLineLayout = Engine.instance.device.createPipelineLayout({
      bindGroupLayouts: uniformsBindGroupLayout,
    });
    // 获取几何体类型
    const GeometryType = config.geometryType;
    //  从mesh组件获取材质类型
    const MaterialType = config.materialType;
    // 获取管线的渲染目标
    let target = {
      format: Engine.instance.format,
    };
    if(config.writeMask!=null||config.writeMask!=undefined){
      target.writeMask=config.writeMask
    }
    // 处理混合模式
    if (config.blendMode) {
      target.blend =
        config.blendMode && Object.keys(config.blendMode).length
          ? config.blendMode
          : undefined;
    }
    let targets = [];
    targets.push(target); //默认加一个
    if (Engine.instance.enableGbuffer) {
      targets.push({ format: "rgba16float" });
      targets.push({ format: "rgba16float" });
    }
    if (Engine.instance.enablePick) {
      targets.push({
        format: Engine.instance.format,
      });
    }
    //图元装配类型
    let PrimitiveConfig = config.primitive;
    // 获取深度测试和模板测试的配置
    let DepthStencil = config.depthStencil;
    // 获取顶点着色器
    const vertexShader = Engine.instance.res.getShader(GeometryType, _defs);
    // 获取片元着色器
    const fragmentShader = Engine.instance.res.getShader(MaterialType, _defs);
    const pipeline = Engine.instance.device.createRenderPipeline({
      //Async
      label: "Pipline",
      layout: pipeLineLayout,
      vertex: {
        module: Engine.instance.device.createShaderModule({
          code: vertexShader,
        }),
        entryPoint: "main",
        buffers: vetexLayout,
      },
      fragment: {
        module: Engine.instance.device.createShaderModule({
          code: fragmentShader,
        }),
        entryPoint: "main",
        targets: targets,
        constants: {
          GAMM: Engine.instance.gamma,
        },
      },
      primitive: PrimitiveConfig,
      depthStencil: DepthStencil,
      multisample: {
        count: Engine.instance.multisample ? 4 : 1,
      },
    });
    return pipeline;
  }
  clear() {
    this.pipes.clear();
  }
}
export { PipeManager };
